#include "cleosgoldguts.h"

////////////////////////////////////////////////////////////////////////////
/// @fn 	 CleosGoldGuts::classifyStops()   
///
/// @param   stops      The array of stop positions for the line.
/// @param   bet        The value of the line bet.
/// @param   line       The index of the line.
///
/// @return	 uint8      A payout from the SpinResult enumeration as a uint8.    
///
/// This helper method is used to calculate the payout on a line.
////////////////////////////////////////////////////////////////////////////
void
CleosGoldGuts::classifyStops(SpinLine* spinline, uint8* stops,uint8 bet, uint8 line, uint8& rtnresult, uint8& multiplier)
{
	SpinResult result            = EVT_LOSER; // spin result :)
	uint8      testIcon          = BLANK;     // Icon at current position
	uint8      iconThatIsNotCleo = BLANK;     // Holder for an Icon that is NOT cleopatra
	uint8      cleoCount         = 0;	      // Has a WILD icon (a cleopatra icon) in the sequence
    bool8      bFirstIconIsCleo  = false;     // Cleo in the first spot means it can stand alone OR substitute

    // By default everything pays at a x1 multiplier
    multiplier = 1;

	//Now, go through the rest, until the streak is over
	for ( uint8 i = 0; (i < getReelCount()); i++ )
    {
		testIcon = getIcon(getGameModeId(), i, stops[i])->iconid;

        // Check to see if it is cleo (we bump the count and continue looking)
        if ( testIcon == CLEO )
        {
            if ( i == 0 )
            {
                bFirstIconIsCleo = true;
            }

            if ( iconThatIsNotCleo == BLANK )
            {
                cleoCount++;
            }
            else
            {
                cleoCount = 1;
            }
        }
        // Pyramids don't pay on individual lines, 
        // just as scatters.
        else if ( testIcon == PYRAMID )
        {
            break;
        }
        else
        {
            // If we haven't found our first non cleo icon, store it off.
            if ( iconThatIsNotCleo == BLANK )
            {
                iconThatIsNotCleo = testIcon;
            }
            // If we have found our fist non cleo icon, and this icon was not cleo
            // or pyramid (those were checked above) and it is not the same as
            // the first non cleo icon, then our evaluation stops.
            else if ( iconThatIsNotCleo != testIcon )
            {
                break;
            }
        }
    }

	//All other Icons EVAL
	switch(iconThatIsNotCleo)
	{
		case SCARAB:
			if ( i == 5 )
			{
                result = EVT_FIVE_SCARAB;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_SCARAB;
			}
			else if (i == 3)
            {
                result = EVT_THREE_SCARAB;
			}
			else if (i == 2)
            {
                result = EVT_TWO_SCARAB;
			}
			break;

		case EYE:
			if ( i == 5 )
			{
                result = EVT_FIVE_EYE_OF_HORUS;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_EYE_OF_HORUS;
			}
			else if (i == 3)
            {
                result = EVT_THREE_EYE_OF_HORUS;
			}
			else if (i == 2)
            {
                result = EVT_TWO_EYE_OF_HORUS;
			}
			break;

        case CAT:
			if ( i == 5 )
			{
                result = EVT_FIVE_CAT;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_CAT;
			}
			else if (i == 3)
            {
                result = EVT_THREE_CAT;
			}
			else if (i == 2)
            {
                result = EVT_TWO_CAT;
			}
			break;

        case ANKH:
			if ( i == 5 )
			{
                result = EVT_FIVE_ANKH;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_ANKH;
			}
			else if (i == 3)
            {
                result = EVT_THREE_ANKH;
			}
			else if (i == 2)
            {
                result = EVT_TWO_ANKH;
			}			
            break;		
		
        case ACE:
			if ( i == 5 )
			{
                result = EVT_FIVE_ACE;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_ACE;
			}
			else if (i == 3)
            {
                result = EVT_THREE_ACE;
			}
			break;

        case KING:
			if ( i == 5 )
			{
                result = EVT_FIVE_KING;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_KING;
			}
			else if (i == 3)
            {
                result = EVT_THREE_KING;
			}
            break;

        case QUEEN:
			if ( i == 5 )
			{
                result = EVT_FIVE_QUEEN;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_QUEEN;
			}
			else if (i == 3)
            {
                result = EVT_THREE_QUEEN;
			}
			break;

        case JACK:
			if ( i == 5 )
			{
                result = EVT_FIVE_JACK;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_JACK;
			}
			else if (i == 3)
            {
                result = EVT_THREE_JACK;
			}
			break;

        case TEN:
			if ( i == 5 )
			{
                result = EVT_FIVE_TEN;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_TEN;
			}
			else if (i == 3)
            {
                result = EVT_THREE_TEN;
			}
			break;

        case NINE:
			if ( i == 5 )
			{
                result = EVT_FIVE_NINE;
			}
			else if (i == 4)
            {
                result = EVT_FOUR_NINE;
			}
			else if (i == 3)
            {
                result = EVT_THREE_NINE;
			}

			break;

        // Pyramids and Blanks don't pay.
        case PYRAMID:
        case BLANK:
            break;
        
        // Some unknown symbol is on the reel!
        default:
            ASSERT(false);
            break;
	}

    if ( result > EVT_LOSER && cleoCount > 0 )
    {
        multiplier = MULTIPLIER_CLEOPATRA_SUBSTITUTE;
    }

    // Now, if the player started with Cleo
    // and ended with some other symbol, then
    // it is possible the cleos are worth more 
    // by themselves then they are in combination
    // with another symbol.  Check to see
    // if that is the case and if so, alter the result.
    if ( cleoCount > 1 && bFirstIconIsCleo )
    {
        SpinResult cleoResult = EVT_LOSER;

	    //CLEO Icon EVAL
	    if(cleoCount == 5 )
	    {
		    cleoResult = EVT_FIVE_CLEOPATRA;
	    }
	    else if (cleoCount == 4)
	    {
		    cleoResult = EVT_FOUR_CLEOPATRA;
	    }
	    else if (cleoCount == 3)
	    {
		    cleoResult = EVT_THREE_CLEOPATRA;
	    }
	    else if (cleoCount == 2)
	    {
		    cleoResult = EVT_TWO_CLEOPATRA;
	    }

        if ( getPayout(cleoResult)->payoutAmount > ((getPayout(result)->payoutAmount)*multiplier) )
        {
            result = cleoResult;
            multiplier = 1;
        }
    }

    if ( multiplier == MULTIPLIER_CLEOPATRA_SUBSTITUTE )
    {
        spinline->addNote(NOTE_CLEO_SUBSTITUTION_2X);
    }

    rtnresult = (uint8) result;	
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 CleosGoldGuts::classifyScatters()   
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This is an override of the framework method.  
/// It determines if the current spin merits free spins or scatter payments.
////////////////////////////////////////////////////////////////////////////
void 
CleosGoldGuts::classifyScatters(SlotSpin *spin)
{	
	uint8 numPyramidIcons = 0;
    int32 pyramidScatterPositions = 0;
	uint8 stop = 0;
	uint8 whichItem = BLANK;
    uint8 position = 0;
    uint8 multiplier = ( getGameModeId() == MODE_FREE_SPIN )  ? MULTIPLIER_FREE_SPIN : 1;

	spin->clearScatters();

	// if we are in the first paid spin (NOT a bonus spin) try for the Random Progressive Jackpot
	if (getGameModeId() == MODE_NORMAL ) 
	{
		if ( getRandomProgressiveJackpotResult(spin->getSpinLineCount()) ||
			 m_bForceRandomJackpot )
        {
	        spin->addScatter( 0, 
                              getPayout(EVT_RANDOM_PROGRESSIVE_WINNER)->payoutAmount, 
                              1,
                              true,
                              EVT_RANDOM_PROGRESSIVE_WINNER,
                              0 );
        }
    }

	for(int row = 0; row < 3; row++)
	{
  		for(int reel = 0; reel<5; reel++)
		{
			stop = relativeWheelPosition(getGameModeId(), reel, spin->getStops()[reel], row);
			whichItem = getIcon(getGameModeId(), reel, stop)->iconid;
			
			if ( whichItem == PYRAMID )
			{
				numPyramidIcons++;
                pyramidScatterPositions += 1<<position;
            }

            position++;
		} // reel
	} // row

    int32  freespins = 0;

	if (numPyramidIcons >= 1 )
    {
        uint8 payouttypeid = EVT_SCATTER_NEAR_MISS;

	    switch ( numPyramidIcons )
	    {
	       case 1:
                payouttypeid = EVT_SCATTER_NEAR_MISS;
                break;

           case 2: 
                payouttypeid = EVT_TWO_PYRAMID;
                break;
	       case 3: 
                payouttypeid = EVT_THREE_PYRAMID;
                freespins = 15;		
			    setGameModeId(MODE_FREE_SPIN);
                break;

	       case 4: 
                payouttypeid = EVT_FOUR_PYRAMID;
                freespins = 15;		
			    setGameModeId(MODE_FREE_SPIN);
                break;

           case 5: 
                payouttypeid = EVT_FIVE_PYRAMID;
                freespins = 15;		
			    setGameModeId(MODE_FREE_SPIN);
                break;
	    };

        int32 nPayout = getPayout(payouttypeid)->payoutAmount * ( spin->getSpinLineCount());

        increaseTotalWin(nPayout*multiplier );

	    SlotScatter* pScatter = spin->addScatter( pyramidScatterPositions, 
                                                  nPayout*getBetPerLine(),
                                                  multiplier,
                                                  false,
                                                  payouttypeid,
                                                  0 );
        
        if ( multiplier == MULTIPLIER_FREE_SPIN )
        {
            pScatter->addNote(NOTE_FREE_SPIN_3X);
        }

        if ( freespins > 0 )
        {
            incrementFreeSpins(freespins);
	        spin->addScatter( pyramidScatterPositions, 
                              0,
                              0,
                              false,
                              EVT_FREE_GAMES,
                              freespins );  
        }

    }
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 CleosGoldGuts::isValidGuts()   
///
/// @return	 bool8      True if gut is valid.    
///
/// This helper method is used to the current gut ID is valid.
////////////////////////////////////////////////////////////////////////////
bool8 
CleosGoldGuts::isValidGuts()
{
    return (getGutsId() >= 200 && getGutsId() < 300);
}

void 
CleosGoldGuts::getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId )
{
    if ( getGameModeId() == MODE_FREE_SPIN )
    {
        nGameModeMultiplier = MULTIPLIER_FREE_SPIN;
        nNoteId = NOTE_FREE_SPIN_3X;
    }
    else
    {
        SlotGuts::getGameModeMultiplierAndNoteId( nGameModeMultiplier, nNoteId );
    }
}


////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	Debugging code
//
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
/// @fn 	 CleosGoldGuts::preSpinClassifyResults()   
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This method is overridden in debug spins mode to alter the reel stops.
////////////////////////////////////////////////////////////////////////////
void 
CleosGoldGuts::preSpinClassifyResults( SlotSpin* spin )
{
	SlotGuts::preSpinClassifyResults(spin);
	return;
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 CleosGoldGuts::Debug_SetLoserStops( uint8* pStops )
///
/// @param   pStops		The stops to set.
///
/// Base class override, returns a losing spin triggered by the debug tool
////////////////////////////////////////////////////////////////////////////
void CleosGoldGuts::Debug_SetLoserStops( uint8* pStops )
{
	pStops[0]=0;
	pStops[1]=3;
	pStops[2]=0;
	pStops[3]=0;
	pStops[4]=0;
}


////////////////////////////////////////////////////////////////////////////////
// Bodog Life Slots, a Cleopatra clone
// Added by Alex Oren, 2007-11-28
////////////////////////////////////////////////////////////////////////////////

// Overrides the Cleopatra's Gold behaviour: base 
bool8 DirtyMartiniGuts::isValidGuts()
{
	int32 gutsId = getGutsId();
	return (gutsId >= 8200 && gutsId < 8300);
}
